'*******************************************************************************
' *  
' *  Product: GSALib
' *  Description: A C# API for accessing the Google Search Appliance.
' *
' *  (c) Copyright 2008 Michael Cizmar + Associates Ltd.  (MC+A)
' *  
'*******************************************************************************


Imports System
Imports System.Collections.Generic
Imports System.Configuration
Imports System.Text
Imports System.IO
Imports System.Net

Namespace GSALib.GSA
    ''' <summary>
    ''' Class provides Methods to access to GSA by specified host
    ''' <para>Author Albert Ghukasyan</para>    
    ''' </summary>
    Public NotInheritable Class ClientAccess
#Region "Variables"

        Private protocol As String
        Private host As String
        Private path As String
        Private port As Integer
        Public GSAHostAddress As String = ""

        Public Const DEFAULT_PORT As Integer = 80
        Public Const DEFAULT_PATH As String = "/search"
        Public Const DEFAULT_PROTOCOL As String = "http"
        Private NeedCredentails As Boolean = False
        Public credentails As NetworkCredential

#End Region

#Region "Contructors"

        ''' <summary>
        ''' Constructor wich Creates ClientAccess Object with Specified Host,Port,Protocol and path
        ''' </summary>
        ''' <param name="protocol">Protocol (Default is http:// )</param>
        ''' <param name="host">Host of GSA Server</param>
        ''' <param name="port">Port of GSA Server(Default is 80)</param>        
        ''' <param name="path">Path(Default is "/Search" )</param>
        Public Sub New(ByVal protocol As String, ByVal host As String, ByVal port As Integer, ByVal path As String)
            InitializeHost(protocol, host, port, path)
        End Sub

        ''' <summary>
        ''' Constructor wich Creates ClientAccess Object with DEFAULT_PROTOCOL
        ''' </summary>
        ''' <param name="host">Host of GSA Server</param>
        ''' <param name="port">Port of GSA Server(Default is 80)</param>        
        ''' <param name="path">Path(Default is "/Search" )</param>
        Public Sub New(ByVal host As String, ByVal port As Integer, ByVal path As String)
            InitializeHost(DEFAULT_PROTOCOL, host, port, path)
        End Sub

        ''' <summary>
        ''' Constructor wich Creates ClientAccess Object with DEFAULT_PROTOCOL and PORT
        ''' </summary>
        ''' <param name="host">Host of GSA Server</param>
        ''' <param name="path">Path(Default is "/Search" )</param>
        Public Sub New(ByVal host As String, ByVal path As String)
            InitializeHost(DEFAULT_PROTOCOL, host, DEFAULT_PORT, path)
        End Sub

        ''' <summary>
        ''' Constructor wich Creates ClientAccess Object with DEFAULT_PROTOCOL,PORT and Search Path
        ''' </summary>
        ''' <param name="host">Host of GSA Server</param>
        Public Sub New(ByVal host As String)
            InitializeHost(DEFAULT_PROTOCOL, host, DEFAULT_PORT, DEFAULT_PATH)
        End Sub

        ''' <summary>
        ''' Default Contructor
        ''' </summary>
        Public Sub New()
            InitializeHost(DEFAULT_PROTOCOL, Nothing, DEFAULT_PORT, DEFAULT_PATH)
        End Sub

        ''' <summary>
        ''' Initializing of Members
        ''' </summary>       
        Private Sub InitializeHost(ByVal protocol As String, ByVal host As String, ByVal port As Integer, ByVal path As String)
            If host IsNot Nothing Then
                Me.protocol = protocol
                Me.host = host
                Me.port = port
                Me.path = path
            End If

            Try
                Me.GSAHostAddress = Me.GetConfig()
            Catch ex As GSALib.Exceptions.GSAHostNotFoundInAppSettingsException
                Throw ex
            Catch ex As FileNotFoundException
                Throw ex
            End Try

        End Sub

#End Region

#Region "Read host data from .cofig file"

        ''' <summary>
        ''' Reads GSAHostAddress from the Application/Web config file
        ''' </summary>
        ''' <returns>GSAHostAddress specified in Configuration file</returns>
        Private Function GetConfig() As String
            Dim Result As String = ""

            Try
                Result = ConfigurationManager.AppSettings("GSAHostAddress")

                If Result.Length <= 0 Then
                    Throw New GSALib.Exceptions.GSAHostNotFoundInAppSettingsException("GSAHostAddress key not found in appSettings section", "")
                End If
            Catch ex As Exception
                Throw ex
            End Try

            Return Result
        End Function

#End Region

#Region "Get Properties"

        Public Function getHost() As String
            Return host
        End Function

        Public Function getPath() As String
            Return path
        End Function

        Public Function getPort() As Integer
            Return port
        End Function

        Public Function getProtocol() As String
            Return protocol
        End Function

#End Region

#Region "Methods"

        ''' <summary>
        ''' Default Search
        ''' </summary>
        ''' <param name="query">Query class object</param>
        ''' <returns></returns>
        Public Function search(ByVal query As Query) As StreamReader
            If query.getAccess() <> "p"c Then
                Me.NeedCredentails = True
            End If

            Return search(query.getValue())
        End Function

        ''' <summary>
        ''' Getting full URL
        ''' </summary>
        ''' <param name="rawQuery">Query to append</param>
        ''' <returns></returns>
        Public Function GetFullPath(ByVal rawQuery As String) As String
            Dim fullUrl As String = rawQuery
            If rawQuery.IndexOf("://") < 0 Then
                ' build full url
                fullUrl = IIf(Me.host Is Nothing, GSAHostAddress + DEFAULT_PATH + (IIf(rawQuery.StartsWith("?"), rawQuery, ("?" + rawQuery))), protocol + "://" + host + ":"c + port + (IIf(path.StartsWith("/"), path, ("/" + path))) + (IIf(rawQuery.StartsWith("?"), rawQuery, ("?" + rawQuery))))
            End If

            Return fullUrl
        End Function

        ''' <summary>
        ''' Search in WEB by specified Query
        ''' </summary>        
        ''' <returns> Stream wich contains response Steram of results from GSA</returns>
        Private Function search(ByVal rawQuery As String) As StreamReader
            Dim retval As StreamReader = Nothing

            If rawQuery IsNot Nothing Then
                Dim rew As WebRequest = WebRequest.Create(GetFullPath(rawQuery))
                If Me.NeedCredentails AndAlso credentails IsNot Nothing Then
                    rew.Credentials = credentails
                ElseIf Me.NeedCredentails Then
                    Throw New Exceptions.GSANeedNetworkCredentailsException("Please specify NTLM credentails", "")
                End If

                retval = New StreamReader(rew.GetResponse().GetResponseStream(), True)
            End If
            Return retval
        End Function

        ''' <summary>
        ''' Sending Response to gsa host and data retrieving
        ''' </summary>
        ''' <param name="query"></param>
        ''' <param name="path">Set to null if you dont want to save in file</param>
        ''' <returns></returns>
        Public Function getGSAResponse(ByVal query As Query, ByVal path As String) As Response
            Dim readStream As StreamReader = search(query)

            Dim rsp As New ResponseBuilder()
            '(readStream, GSAHostAddress);
            Return rsp.buildResponse(readStream, GSAHostAddress, path)
            ' ResponseBuilder.buildResponse(search(rawQuery), xmlSystemId);
        End Function

#End Region
    End Class
End Namespace
